import { cloneDeep } from "lodash";
import { saveAs } from "file-saver";
import storage from "@/utils/storage";
import router from '@/router'

export const getMenuID = () => {
  const menuCode = router.currentRoute.params.menuCode;
  return menuCode;
};

export function isUserName(userName) {
  const reg = /^[a-zA-Z0-9_-]{6,18}$/;
  return reg.test(userName);
}

//通过比较对象KEY值，对象数组去重方法，非对象数组去重请直接使用[...new Set(array)]
export const arrayReduceDuplication = (array, key) => {
  let obj = {};
  return array.reduce((cur, next) => {
    obj[next[key]] ? "" : (obj[next[key]] = true && cur.push(next));
    return cur;
  }, []);
};

export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null;
  }
  const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
  let date;
  if (typeof time === "object") {
    date = time;
  } else {
    if (("" + time).length === 10) time = parseInt(time) * 1000;
    date = new Date(time);
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  };
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key];
    if (key === "a")
      return ["一", "二", "三", "四", "五", "六", "日"][value - 1];
    if (result.length > 0 && value < 10) {
      value = "0" + value;
    }
    return value || 0;
  });
  return time_str;
}

// 格式化时间
export function formatTime(time, option) {
  time = +time * 1000;
  const d = new Date(time);
  const now = Date.now();

  const diff = (now - d) / 1000;

  if (diff < 30) {
    return "刚刚";
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + "分钟前";
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + "小时前";
  } else if (diff < 3600 * 24 * 2) {
    return "1天前";
  }
  if (option) {
    return parseTime(time, option);
  } else {
    return (
      d.getMonth() +
      1 +
      "月" +
      d.getDate() +
      "日" +
      d.getHours() +
      "时" +
      d.getMinutes() +
      "分"
    );
  }
}

// 获取url对象
export function getQueryObject(url) {
  url = url == null ? window.location.href : url;
  const search = url.substring(url.lastIndexOf("?") + 1);
  const obj = {};
  const reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
}

export function cleanArray(actual) {
  const newArray = [];
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

export function param(json) {
  if (!json) return "";
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return "";
      return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
    })
  ).join("&");
}

export function scrollTo(element, to, duration) {
  if (duration <= 0) return;
  const difference = to - element.scrollTop;
  const perTick = (difference / duration) * 10;
  setTimeout(() => {
    element.scrollTop = element.scrollTop + perTick;
    if (element.scrollTop === to) return;
    scrollTo(element, to, duration - 10);
  }, 10);
}

export function getTime(type) {
  if (type === "start") {
    return new Date().getTime() - 3600 * 1000 * 24 * 90;
  } else {
    return new Date(new Date().toDateString());
  }
}

// 函数防抖
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result;

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };

  return function(...args) {
    context = this;
    timestamp = +new Date();
    const callNow = immediate && !timeout;
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait || 1000);
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }

    return result;
  };
}

export function toPosInt(val) {
  return Math.abs(val) >>> 0;
}

// 函数节流
export function throttle(fn, wait, context) {
  var timer;
  return function(...args) {
    if (!timer) {
      timer = setTimeout(() => (timer = null), wait || 1000);
      return fn.apply(context || this, args);
    }
  };
}

// 深拷贝
export function deepClone(source) {
  // return JSON.parse(JSON.stringify(source));
  return cloneDeep(source);
}

//  浮动
// 参数docP 父级document
// 参数docC 子级document
export function positionDoc(docP, docC) {
  if (docP == "" || docP == undefined || docC == "" || docC == undefined) {
    return;
  } else {
    let mainTable = document.querySelector(docP),
      congTable = document.querySelector(docC),
      mainTableChild = mainTable.getElementsByClassName(
        "el-table__header-wrapper"
      )[0],
      widthUpdate = () => {
        let clientHeight = document.documentElement.clientHeight,
          scrollHeight = document.documentElement.scrollHeight,
          scrollTop =
            document.documentElement.scrollTop || document.body.scrollTop;
        if (scrollHeight <= clientHeight) {
          congTable.style.position = "relative";
          congTable.style.width = "auto";
          congTable.style.right = 0;
        } else {
          congTable.style.position = "fixed";
          congTable.style.right = 28 + "px";
          congTable.style.width =
            mainTable.getBoundingClientRect().width + "px";
        }
        if (scrollTop >= 200) {
          mainTableChild.style.position = "fixed";
          mainTableChild.style.top = 0;
        } else {
          mainTableChild.style.position = "relative";
        }
      };
    setTimeout(() => {
      widthUpdate();
    });
    window.onresize = widthUpdate;
    window.onscroll = () => {
      let clientHeight = document.documentElement.clientHeight,
        scrollHeight = document.documentElement.scrollHeight,
        scrollTop =
          document.documentElement.scrollTop || document.body.scrollTop;
      if (scrollHeight <= clientHeight) {
        return;
      } else {
        if (clientHeight + scrollTop + 50 >= scrollHeight) {
          congTable.style.position = "relative";
          congTable.style.width = "auto";
          congTable.style.right = 0;
        } else {
          congTable.style.position = "fixed";
          congTable.style.right = 28 + "px";
          congTable.style.width =
            mainTable.getBoundingClientRect().width + "px";
        }
      }
      if (scrollTop >= 200) {
        mainTableChild.style.position = "fixed";
        mainTableChild.style.top = 0;
      } else {
        mainTableChild.style.position = "relative";
      }
    };
  }
}
//底部悬浮
export function footFixed(docP, docC) {
  if (docP === "" || docP === undefined || docC === "" || docC === undefined) {
    return;
  } else {
    let docHtml = document.querySelector(docP),
      docHtmls = document.querySelector(docC),
      widthUpdate = () => {
        docHtmls.style.width = docHtml.offsetWidth + "px";
      };
    widthUpdate();
    window.onresize = widthUpdate;
  }
}

export const isArrayObject = obj => {
  if (typeof Array.isArray === "function") {
    return Array.isArray(obj);
  } else {
    return Object.prototype.toString.call(obj) === "[object Array]";
  }
};

export const browserDownload = url => {
  saveAs(url, url.substring(url.lastIndexOf("/") + 1));
  // var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
  // //地址
  // save_link.href = url;
  // save_link.download = name;
  // var ev = document.createEvent("MouseEvents");
  // ev.initMouseEvent(
  //   "click",
  //   true,
  //   false,
  //   window,
  //   0,
  //   0,
  //   0,
  //   0,
  //   0,
  //   false,
  //   false,
  //   false,
  //   false,
  //   0,
  //   null
  // );
  // save_link.dispatchEvent(ev);
};

//对象数组根据属性升序排序
export function compareUp(data, propertyName) {
  // 升序排序
  if (typeof data[0][propertyName] != "number") {
    // 属性值为非数字
    return function(object1, object2) {
      var value1 = object1[propertyName];
      var value2 = object2[propertyName];
      return value1.localeCompare(value2);
    };
  } else {
    return function(object1, object2) {
      // 属性值为数字
      var value1 = object1[propertyName];
      var value2 = object2[propertyName];
      return value1 - value2;
    };
  }
}

//对象数组根据属性降序排序
export function compareDown(data, propertyName) {
  // 降序排序
  if (typeof data[0][propertyName] != "number") {
    // 属性值为非数字
    return function(object1, object2) {
      var value1 = object1[propertyName];
      var value2 = object2[propertyName];
      return value2.localeCompare(value1);
    };
  } else {
    return function(object1, object2) {
      // 属性值为数字
      var value1 = object1[propertyName];
      var value2 = object2[propertyName];
      return value2 - value1;
    };
  }
}

// 获取默认值
export function isDefault(arr) {
  if (typeof arr === "object") {
    const obj = arr.find(val => val.is_default && val.is_default == 1);
    if (obj) {
      return obj.id;
    } else {
      return "";
    }
  }
}

/**
 * @description 格式化输入的重量。过滤重量输入框中的非法字符串，根据后台接口返回保留相应小数位数
 * @param {Object} param vm {Object} vue 实例
 * @param {Object} param oldValue {String} 原来输入的值
 * @param {Object} param negative {Boolean} 是否可以输入负数
 */
export function resetInputWeight(vm, oldValue, negative = false) {
  oldValue = oldValue.toString();
  let resetValue = "";
  let pointResult = oldValue.match(/./g) || [];
  let anyPoint = pointResult.filter(s => s == ".").length > 1;
  if (anyPoint || (pointResult[0] == 0 && pointResult[1] == 0)) {
    resetValue = "";
  } else {
    const weight_format = vm.$store.getters.weight_format;
    if (negative) {
      resetValue = oldValue.replace(/[^\d-.]/g, "");
      let pattern = new RegExp(
        `(-|\\+)?(\\d+)?(\\.?)(\\d{0,${weight_format}})`
      );
      let newValue = resetValue.match(pattern);
      resetValue = (newValue && newValue[0]) || "";
    } else {
      resetValue = oldValue.replace(/[^\d.]/g, "");
      let pattern = new RegExp(`(\\d+)?(\\.?)(\\d{0,${weight_format}})`);
      let newValue = resetValue.match(pattern);
      resetValue = (newValue && newValue[0]) || "";
    }
  }
  return resetValue;
}

/**
格式化输入的金额(所有的单价和所有的金额)。过滤金额输入框中的非法字符串
 * @param {Object} param oldValue {String} 原来输入的值
 * @param {Object} param negative {Boolean} 是否可以输入负数
 */
export function resetInputMoney(oldValue, negative = false) {
  oldValue = oldValue.toString();
  let resetValue = "";
  let pointResult = oldValue.match(/./g) || [];
  let anyPoint = pointResult.filter(s => s == ".").length > 1;
  if (anyPoint || (pointResult[0] == 0 && pointResult[1] == 0)) {
    resetValue = "";
  } else {
    if (negative) {
      resetValue = oldValue.replace(/[^\d-.]/g, "");
      let newValue = resetValue.match(/(-|\+)?(\d+.)?(\d{0,2})/);
      resetValue = (newValue && newValue[0]) || "";
    } else {
      resetValue = oldValue.replace(/[^\d.]/g, "");
      let newValue = resetValue.match(/(\d+.)?(\d{0,2})/);
      resetValue = (newValue && newValue[0]) || "";
    }
  }
  return resetValue;
}

/**
 * @description 格式化输入的数量。过滤数量输入框中的非法字符串
 * @param {Object} param oldValue {String} 原来输入的值
 * @param {Object} param negative {Boolean} 是否可以输入负数
 */
export function resetInputQuantity(oldValue, negative = false) {
  oldValue = oldValue.toString();
  let resetValue = "";
  if (negative) {
    resetValue = oldValue.replace(/[^\d-]/g, "");
  } else {
    resetValue = oldValue.replace(/[^\d]/g, "");
  }
  return resetValue;
}

// 将时间戳转换成时间描述
export function getTimeDesc(time) {
  var _n = 12 * 30 * 24 * 60 * 60 * 1000,
    _y = 30 * 24 * 60 * 60 * 1000,
    _d = 24 * 60 * 60 * 1000,
    _h = 60 * 60 * 1000,
    _m = 60 * 1000,
    _s = 1000,
    n,
    y,
    d,
    h,
    m,
    s,
    value;

  n = parseInt(time > _n ? time / _n : 0);
  n = n ? n + "年" : "";
  time = time % _n;

  y = parseInt(time > _y ? time / _y : 0);
  y = y ? y + "月" : "";
  time = time % _y;

  d = parseInt(time > _d ? time / _d : 0);
  d = d ? d + "天" : "";
  time = time % _d;

  h = parseInt(time > _h ? time / _h : 0);
  h = h ? h + "时" : "";
  time = time % _h;

  m = parseInt(time > _m ? time / _m : 0);
  m = m ? m + "分" : "";
  time = time % _m;

  s = parseInt(time > _s ? time / _s : 0);
  s = s + "秒";

  value = n + y + d + h + m + s;

  return value;
}

// 清除cookie
export function clearCookie() {
  var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
  if (keys) {
    for (var i = keys.length; i--; )
      document.cookie = keys[i] + "=0;expires=" + new Date(0).toUTCString();
  }
}

// 半角转化为全角
export function ToDBC(txtstring) {
  var tmp = "";
  for (var i = 0, len = txtstring.length; i < len; i++) {
    if (txtstring.charCodeAt(i) == 32) {
      tmp = tmp + String.fromCharCode(12288);
    }
    if (txtstring.charCodeAt(i) < 127) {
      tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248);
    }
  }
  return tmp;
}

// 全角转换为半角
export function ToCDB(str) {
  var tmp = "";
  for (var i = 0, len = str.length; i < len; i++) {
    if (str.charCodeAt(i) == 12288) {
      tmp += String.fromCharCode(str.charCodeAt(i) - 12256);
      continue;
    }
    if (str.charCodeAt(i) > 65280 && str.charCodeAt(i) < 65375) {
      tmp += String.fromCharCode(str.charCodeAt(i) - 65248);
    } else {
      tmp += String.fromCharCode(str.charCodeAt(i));
    }
  }
  return tmp;
}

// 对象数组去重
export const groupBy = (array, f) => {
  let groups = {};
  array.forEach(function(o) {
    let group = JSON.stringify(f(o));
    groups[group] = groups[group] || [];
    groups[group].push(o);
  });
  return Object.keys(groups).map(function(group) {
    return groups[group];
  });
};

// 设置表格合并行数
export function setTableSpans(dataList, key) {
  let contactDot = 0,
    spanArr = [];
  dataList.forEach((item, index) => {
    if (index < 1) {
      spanArr.push(1);
    } else {
      if (item[key] === dataList[index - 1][key]) {
        spanArr[contactDot] += 1;
        spanArr.push(0);
      } else {
        contactDot = index;
        spanArr.push(1);
      }
    }
  });
  return spanArr;
}

export function binterface(item) {
  const transform = (arr)=>{
    return arr.map(i=>{
      if(i.children.length > 0){
        i.children = transform(i.children)
      }
      i.path = i.parentid+"/"+i.id+"/"+i.url
      return i
    })
  }
  item.map(obj => {
    obj.parentid = obj.parentid ?? obj.id
    obj.path = obj.parentid+"/"+obj.id+"/"+obj.url
    obj.children = transform(obj.children)
    // obj.name = obj.MenuName;
    // obj.path = obj.MenuPath;
    // obj.children.map(i => {
      // i.name = i.MenuName;
      // i.path = i.MenuPath;
      // i.children.map(obi => {
      //   obi.name = obi.MenuName;
      //   obi.path = obi.MenuPath;
      //   return obi;
      // });
    //   return i;
    // });
    return obj;
  });
  return { menuTree: item };
}

export function isPasswordSafety(password) {
  const reg = /^(?=.*\d)(?=.*[A-Za-z])[\x20-\x7e]{6,16}$/;
  return reg.test(password);
}

// 转化公共基础数据（大类/品名/材质/规格/厂家），用于element-ui组件
export function transformCommonData(data = []) {
  const newData = data.slice(0, 30);
  return newData.map(item => {
    item.value = item.name;
    return item;
  });
}
